package com.zaicheng.cloud.netty.client;
/**
 @author zaicheng
 @version 1.0
 @date 2022-04-19
 @email zzc15847256473@163.com
 */

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zaicheng.cloud.netty.protocol.MessageContext;
import com.zaicheng.cloud.netty.protocol.Response;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.Map;
import java.util.concurrent.Callable;

public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable<Object>{

    // 设置要发给服务器端的数据
    private ChannelHandlerContext context;
    // 获取服务器端响应的结果
    private Response result;
    // 发送给服务器端的参数
    private MessageContext param;

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
//        ByteBuf buf = Unpooled.copiedBuffer("HelloServer".getBytes(CharsetUtil.UTF_8));
//        ctx.writeAndFlush(buf);
        System.out.println("连接到了服务器,触发了channelActive："+ctx.channel().remoteAddress());
        if (this.context == null){
            this.context = ctx;
        }
    }

    @Override
    public synchronized Object call() throws Exception {
        System.out.println("call方法被调用之前");
        this.context.writeAndFlush(param);
        wait();
        System.out.println("call方法被调用之后");
        result = JSON.parseObject(JSONObject.toJSONString(param.getData()),Response.class);
        return JSON.parseObject(JSONObject.toJSONString(result.getContext()),result.getContextType());
    }

    //当通道有读取事件时会触发，即服务端发送数据给客户端
    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("服务端给客户端响应数据时，触发了channelRead");
        if (msg instanceof MessageContext){
            this.param = (MessageContext) msg;
            notify();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.channel().close();
    }

    public void setParam(MessageContext param) {
        System.out.println("setParam被调用");
        this.param = param;
    }
}
